package com.zhangtai.exception;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangtai.modules.controller.aouthLogin.LoginController;
import com.zhangtai.modules.dao.QwUserDao;
import com.zhangtai.modules.dao.UserDao;
import com.zhangtai.modules.entity.common.NoticeEntity;
import com.zhangtai.modules.entity.common.NoticeRoleEntity;
import com.zhangtai.modules.entity.common.NoticeUserRoleEntity;
import com.zhangtai.modules.entity.employee.EmployeeInfoEntity;
import com.zhangtai.modules.entity.system.UserEntity;
import com.zhangtai.modules.jobTask.qw.QwUserEntity;
import com.zhangtai.modules.service.common.NoticeRoleService;
import com.zhangtai.modules.service.common.NoticeService;
import com.zhangtai.modules.service.common.NoticeUserRoleService;
import com.zhangtai.modules.service.employee.EmployeeInfoService;
import com.zhangtai.modules.service.system.UserService;
import com.zhangtai.utils.R;
import com.zhangtai.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("qw")
public class QwMsg {
    private String sengUrl="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s";
    private static final Integer agentid=1000063;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SendErr sendErr;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private NoticeRoleService noticeRoleService;
    @Autowired
    private NoticeUserRoleService noticeUserRoleService;
    @Autowired
    private UserService userService;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private EmployeeInfoService employeeInfoService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private LoginController loginController;
    @Autowired
    private QwUserDao qwUserDao;


    @Async("Log")
    public void sendNoticeMsg(String msg,String touserId){
        String token = (String) redisTemplate.boundValueOps("QW_TOKEN").get();
        log.info("企微token为:{}",token);
        if (StringUtils.isEmpty(token)){
            token = sendErr.getToken();
        }

        String format = String.format(sengUrl, token);
        JSONObject object = new JSONObject();
        object.put("touser",touserId);
        object.put("msgtype","text");
        object.put("agentid",agentid);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("content",msg);
        object.put("text",jsonObject);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<JSONObject> httpEntity = new HttpEntity<JSONObject>(object,headers);

        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(format, httpEntity, JSONObject.class);
        JSONObject body = responseEntity.getBody();
        log.info("企微消息推送：{}",body.toString());
    }

    /**
     *  发送待办以及普通消息
     *
     * @param content 消息内容
     * @param type 类型（根据待办还是消息推送判断）
     * @param isMsg 是否是消息
     * @param oid 雇员id
     * @param operationId 业务表id
     * @param key 角色名
     * @param code 申请人code(发送消息时用)
     * @return
     */
    @Async("Log")
    public R sendNoticeMsg(String title,String content,Integer type,boolean isMsg,Long oid,Long operationId,String key,String code,Date todoDate, Long orgId){

        //无论是推送给HR还是发消息给个人 都要有雇员id
        log.info("开始推送消息给:{}",code);
        EmployeeInfoEntity employeeInfoEntity = employeeInfoService.getByIdE(oid);
        if(ObjectUtils.isEmpty(employeeInfoEntity)){
            return R.error("雇员信息不存在！");
        }
        //待办接收的HR的code
        String accepterCode = "";
        NoticeEntity noticeEntity = new NoticeEntity();
        noticeEntity.setCreateTime(new Date());
        noticeEntity.setDepartment(employeeInfoEntity.getUnitname());
        noticeEntity.setJobName(employeeInfoEntity.getJobname());
        noticeEntity.setIdCard(noticeEntity.getIdCard());
        noticeEntity.setEntryDate(noticeEntity.getEntryDate());
        noticeEntity.setName(employeeInfoEntity.getName());
        noticeEntity.setOid(employeeInfoEntity.getOid());
        noticeEntity.setTitle(title);
        noticeEntity.setMsg(content);
        //待办消息
        if(!isMsg){
            //如果推送待办时code不为空推个指定的人，如果code为空推给角色下所有人
            if(!StringUtils.isEmpty(code)){
                List<QwUserEntity> qwUserEntitys = qwUserDao.selectList(new QueryWrapper<QwUserEntity>().eq("user_code", code));
                if (!CollectionUtils.isEmpty(qwUserEntitys)){
                    QwUserEntity qwUserEntity = qwUserEntitys.get(0);
                    sendNoticeMsg(content,qwUserEntity.getUserid());
                }
                accepterCode = code;
            }else{
                //根据key查询出对应待办消息角色
                NoticeRoleEntity roleEntity = noticeRoleService.getByKey(key);
                if(ObjectUtils.isEmpty(roleEntity)){
                    return R.ok();
                }
                //获取角色下所有人员
                List<NoticeUserRoleEntity> noticeUserRoleEntityList =  noticeUserRoleService.getAllRoleUser(roleEntity.getNoticeRoleId());
                int i=0;
                for(NoticeUserRoleEntity entity:noticeUserRoleEntityList){
                    UserEntity user = userService.getByIdE(entity.getUserId()) ;
                    if(ObjectUtils.isEmpty(user)){
                        i++;
                        continue;
                    }
                    boolean isSend = false;
                    List<Long> orgIds = (List<Long>) redisTemplate.boundValueOps("orgPermission"+entity.getUserId()).get();
                    if(ObjectUtils.isEmpty(orgIds)){
                        i++;
                        continue;
                    }
                    //判断是否有当前公司组权限
                    for(Long id:orgIds){
                        if(id.equals(orgId)){
                            isSend = true;
                            break;
                        }
                    }
                    //有公司组权限才发送企微以及待办推送
                    if(isSend){
                        sendNoticeMsg(content,user.getQwAccount());
                        //接收人
                        if(i!=noticeUserRoleEntityList.size()-1){
                            accepterCode += user.getUsercode()+",";
                        }else{
                            accepterCode += user.getUsercode();
                        }
                    }

                    i++;
                }
            }
            //保存接收人的sys_user.user_code
            noticeEntity.setAccepterCode(accepterCode);
            noticeEntity.setType(type);
            noticeEntity.setTodoDate(todoDate);
            noticeEntity.setOperationId(operationId);
        }
        //普通消息只发给申请人
        else{
            List<QwUserEntity> qwUserEntitys = qwUserDao.selectList(new QueryWrapper<QwUserEntity>().eq("user_code", code));
            if (!CollectionUtils.isEmpty(qwUserEntitys)){
                QwUserEntity qwUserEntity = qwUserEntitys.get(0);
                noticeEntity.setNoticeType(type);
                sendNoticeMsg(content,qwUserEntity.getUserid());
            }else{
                return R.error("用户不存在！");
            }
        }

        noticeEntity.setTitle(content);
        log.info("消息推送完毕:{}",noticeEntity);
        //插入消息
        noticeService.saveE(noticeEntity);
        return R.ok();
    }


    /**
     *  发送待办以及普通消息
     *
     *      * @param title 消息标题
     *      * @param qwMsg 发的企业微信消息
     *      * @param url 跳转地址
     *      * @param msgType 消息类型 1 文本消息  2 图片消息   3语音消息  4 视频消息 5文件消息  6文本卡片消息 7 图文消息
     *      * @param content 消息内容
     *      * @param type 类型（根据待办还是消息推送判断）
     *      * @param isMsg 是否是消息
     *      * @param oid 雇员id
     *      * @param operationId 业务表id
     *      * @param key 角色名
     *      * @param code 申请人code(发送消息时用)
     * @return
     */
    @Async("Log")
    public R sendNoticeMsgOne(sendQwMsgEntity sendQwMsgEntity){

        //无论是推送给HR还是发消息给个人 都要有雇员id
        log.info("开始推送消息给:{}",sendQwMsgEntity.getCode());
        EmployeeInfoEntity employeeInfoEntity = employeeInfoService.getByIdE(sendQwMsgEntity.getOid());
        if(ObjectUtils.isEmpty(employeeInfoEntity)){
            return R.error("雇员信息不存在！");
        }
        //待办接收的HR的code
        String accepterCode = "";
        NoticeEntity noticeEntity = new NoticeEntity();
        noticeEntity.setCreateTime(new Date());
        noticeEntity.setDepartment(employeeInfoEntity.getUnitname());
        noticeEntity.setJobName(employeeInfoEntity.getJobname());
        noticeEntity.setIdCard(noticeEntity.getIdCard());
        noticeEntity.setEntryDate(noticeEntity.getEntryDate());
        noticeEntity.setName(employeeInfoEntity.getName());
        noticeEntity.setOid(employeeInfoEntity.getOid());
        noticeEntity.setMsg(sendQwMsgEntity.getContent());
        //待办消息
        if(!sendQwMsgEntity.isMsg()){
            //如果推送待办时code不为空推个指定的人，如果code为空推给角色下所有人
            if(!StringUtils.isEmpty(sendQwMsgEntity.getCode())){
                List<QwUserEntity> qwUserEntitys = qwUserDao.selectList(new QueryWrapper<QwUserEntity>().eq("user_code", sendQwMsgEntity.getCode()));
                if (!CollectionUtils.isEmpty(qwUserEntitys)){
                    QwUserEntity qwUserEntity = qwUserEntitys.get(0);
                    sendNoticeMsg(sendQwMsgEntity);
                }
                accepterCode = sendQwMsgEntity.getCode();
            }else{
                //根据key查询出对应待办消息角色
                NoticeRoleEntity roleEntity = noticeRoleService.getByKey(sendQwMsgEntity.getKey());
                if(ObjectUtils.isEmpty(roleEntity)){
                    return R.ok();
                }
                //获取角色下所有人员
                List<NoticeUserRoleEntity> noticeUserRoleEntityList =  noticeUserRoleService.getAllRoleUser(roleEntity.getNoticeRoleId());
                int i=0;
                for(NoticeUserRoleEntity entity:noticeUserRoleEntityList){
                    UserEntity user = userService.getByIdE(entity.getUserId()) ;
                    if(ObjectUtils.isEmpty(user)){
                        i++;
                        continue;
                    }
                    boolean isSend = false;
                    List<Long> orgIds = (List<Long>) redisTemplate.boundValueOps("orgPermission"+entity.getUserId()).get();
                    if(ObjectUtils.isEmpty(orgIds)){
                        i++;
                        continue;
                    }
                    //判断是否有当前公司组权限
                    for(Long id:orgIds){
                        if(id.equals(sendQwMsgEntity.getOrgId())){
                            isSend = true;
                            break;
                        }
                    }
                    //有公司组权限才发送企微以及待办推送
                    if(isSend){
                        sendNoticeMsg(sendQwMsgEntity);
                        //接收人
                        if(i!=noticeUserRoleEntityList.size()-1){
                            accepterCode += user.getUsercode()+",";
                        }else{
                            accepterCode += user.getUsercode();
                        }
                    }

                    i++;
                }
            }
            //保存接收人的sys_user.user_code
            noticeEntity.setAccepterCode(accepterCode);
            noticeEntity.setType(sendQwMsgEntity.getType());
            noticeEntity.setTodoDate(sendQwMsgEntity.getTodoDate());
            noticeEntity.setOperationId(sendQwMsgEntity.getOperationId());
        }
        //普通消息只发给申请人
        else{
            UserEntity user = userDao.selectOne(new QueryWrapper<UserEntity>().eq("usercode",sendQwMsgEntity.getCode()));
            if(ObjectUtils.isEmpty(user)){
                return R.error("用户不存在！");
            }
            noticeEntity.setNoticeType(sendQwMsgEntity.getType());
//            sendNoticeMsg(sendQwMsgEntity);
        }

        noticeEntity.setTitle(sendQwMsgEntity.getContent());
        log.info("消息推送完毕:{}",noticeEntity);
        //插入消息
        noticeService.saveE(noticeEntity);
        return R.ok();
    }


    public void sendNoticeMsg(sendQwMsgEntity sendQwMsgEntity){
        String token = (String) redisTemplate.boundValueOps("QW_TOKEN").get();
        log.info("企微token为:{}",token);
        if (StringUtils.isEmpty(token)){
            token = sendErr.getToken();
        }
        String format = String.format(sengUrl, token);
        JSONObject object = new JSONObject();
        object.put("touser",sendQwMsgEntity.getTouserId());
        object.put("agentid",agentid);
        if(2==sendQwMsgEntity.getMsgType()){
            object.put("msgtype","image");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("media_id",sendQwMsgEntity.getMedia_id());
            object.put("image",jsonObject);
        }else if(3==sendQwMsgEntity.getMsgType()){
            object.put("msgtype","voice");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("media_id",sendQwMsgEntity.getMedia_id());
            object.put("voice",jsonObject);
        }else if(4==sendQwMsgEntity.getMsgType()){
            object.put("msgtype","video");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("media_id",sendQwMsgEntity.getMedia_id());
            jsonObject.put("title",sendQwMsgEntity.getTitle());
            jsonObject.put("description",sendQwMsgEntity.getContent());
            object.put("video",jsonObject);
        }else if(5==sendQwMsgEntity.getMsgType()){
            object.put("msgtype","file");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("media_id",sendQwMsgEntity.getMedia_id());
            object.put("file",jsonObject);
        }else if(6==sendQwMsgEntity.getMsgType()){
            object.put("msgtype","textcard");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("title",sendQwMsgEntity.getTitle());
            jsonObject.put("url",sendQwMsgEntity.getUrl());
            jsonObject.put("description",sendQwMsgEntity.getContent());
            jsonObject.put("btntxt","详情");
            object.put("textcard",jsonObject);
        }else if(7==sendQwMsgEntity.getMsgType()){
            object.put("msgtype","news");
            JSONArray jsonArray=new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("title",sendQwMsgEntity.getTitle());
            jsonObject.put("url",sendQwMsgEntity.getUrl());
            jsonObject.put("description",sendQwMsgEntity.getContent());
            jsonObject.put("picurl",sendQwMsgEntity.getPicurl());
            jsonArray.add(jsonObject);
            object.put("news",jsonArray);
        }else {
            //默认是文本
            object.put("msgtype","text");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("content",(sendQwMsgEntity.getQwMsg().isEmpty()?sendQwMsgEntity.getContent():sendQwMsgEntity.getTitle()+":"+sendQwMsgEntity.getQwMsg()));
            object.put("text",jsonObject);
        }


        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<JSONObject> httpEntity = new HttpEntity<JSONObject>(object,headers);

        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(format, httpEntity, JSONObject.class);
        JSONObject body = responseEntity.getBody();
        log.info("企微消息推送：{}",body.toString());
    }

}
